package com.christina.engine.observer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 事件管理器
 * 负责管理事件的发布、订阅和传播
 * 
 * @author Christina
 */
@Slf4j
@Component
public class EventManager {
    
    private final Map<ProcessingEvent.EventType, List<ProcessingEventListener>> listeners = new ConcurrentHashMap<>();
    private final Map<String, ProcessingEventListener> listenerRegistry = new ConcurrentHashMap<>();
    private final ExecutorService asyncExecutor = Executors.newFixedThreadPool(4);
    private final BlockingQueue<ProcessingEvent> eventQueue = new LinkedBlockingQueue<>();
    private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2);
    
    private volatile boolean running = true;
    
    public EventManager() {
        // 启动事件处理线程
        startEventProcessingThread();
        
        // 启动定期清理线程
        startCleanupThread();
    }
    
    /**
     * 注册事件监听器
     * 
     * @param listener 事件监听器
     */
    public void registerListener(ProcessingEventListener listener) {
        if (listener == null) {
            throw new IllegalArgumentException("Listener cannot be null");
        }
        
        String listenerName = listener.getListenerName();
        if (listenerName == null || listenerName.trim().isEmpty()) {
            throw new IllegalArgumentException("Listener name cannot be null or empty");
        }
        
        // 注册到监听器注册表
        listenerRegistry.put(listenerName, listener);
        
        // 为每种支持的事件类型注册监听器
        for (ProcessingEvent.EventType eventType : ProcessingEvent.EventType.values()) {
            if (listener.supportsEventType(eventType)) {
                listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(listener);
            }
        }
        
        // 按优先级排序
        listeners.values().forEach(this::sortListenersByPriority);
        
        log.info("Registered event listener: {} for {} event types", 
                listenerName, getListenerEventTypes(listener).size());
    }
    
    /**
     * 注销事件监听器
     * 
     * @param listenerName 监听器名称
     */
    public void unregisterListener(String listenerName) {
        ProcessingEventListener listener = listenerRegistry.remove(listenerName);
        if (listener != null) {
            // 从所有事件类型的监听器列表中移除
            listeners.values().forEach(list -> list.remove(listener));
            log.info("Unregistered event listener: {}", listenerName);
        }
    }
    
    /**
     * 发布事件（同步）
     * 
     * @param event 事件
     */
    public void publishEvent(ProcessingEvent event) {
        if (event == null) {
            return;
        }
        
        try {
            eventQueue.offer(event, 1, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.warn("Failed to queue event: {}", event.getEventId());
        }
    }
    
    /**
     * 发布事件（异步）
     * 
     * @param event 事件
     */
    public void publishEventAsync(ProcessingEvent event) {
        if (event == null) {
            return;
        }
        
        asyncExecutor.submit(() -> publishEvent(event));
    }
    
    /**
     * 批量发布事件
     * 
     * @param events 事件列表
     */
    public void publishEvents(List<ProcessingEvent> events) {
        if (events == null || events.isEmpty()) {
            return;
        }
        
        for (ProcessingEvent event : events) {
            publishEvent(event);
        }
    }
    
    /**
     * 处理单个事件
     * 
     * @param event 事件
     */
    private void processEvent(ProcessingEvent event) {
        if (event.isExpired()) {
            log.debug("Skipping expired event: {}", event.getEventId());
            return;
        }
        
        List<ProcessingEventListener> eventListeners = listeners.get(event.getEventType());
        if (eventListeners == null || eventListeners.isEmpty()) {
            log.debug("No listeners found for event type: {}", event.getEventType());
            return;
        }
        
        // 过滤启用的监听器
        List<ProcessingEventListener> enabledListeners = eventListeners.stream()
                .filter(ProcessingEventListener::isEnabled)
                .collect(Collectors.toList());
        
        if (enabledListeners.isEmpty()) {
            log.debug("No enabled listeners found for event type: {}", event.getEventType());
            return;
        }
        
        // 分别处理同步和异步监听器
        List<ProcessingEventListener> syncListeners = new ArrayList<>();
        List<ProcessingEventListener> asyncListeners = new ArrayList<>();
        
        for (ProcessingEventListener listener : enabledListeners) {
            if (listener.isAsync()) {
                asyncListeners.add(listener);
            } else {
                syncListeners.add(listener);
            }
        }
        
        // 处理同步监听器
        for (ProcessingEventListener listener : syncListeners) {
            processEventWithListener(event, listener);
        }
        
        // 处理异步监听器
        for (ProcessingEventListener listener : asyncListeners) {
            asyncExecutor.submit(() -> processEventWithListener(event, listener));
        }
    }
    
    /**
     * 使用指定监听器处理事件
     * 
     * @param event 事件
     * @param listener 监听器
     */
    private void processEventWithListener(ProcessingEvent event, ProcessingEventListener listener) {
        try {
            long startTime = System.currentTimeMillis();
            listener.onEvent(event);
            long duration = System.currentTimeMillis() - startTime;
            
            if (log.isDebugEnabled()) {
                log.debug("Processed event {} with listener {} in {}ms", 
                        event.getEventId(), listener.getListenerName(), duration);
            }
            
            // 记录性能指标
            if (duration > 1000) { // 超过1秒的处理记录警告
                log.warn("Slow event processing: {} took {}ms in listener {}", 
                        event.getEventId(), duration, listener.getListenerName());
            }
            
        } catch (Exception e) {
            log.error("Error processing event {} with listener {}", 
                    event.getEventId(), listener.getListenerName(), e);
            
            try {
                listener.onError(event, e);
            } catch (Exception errorHandlingException) {
                log.error("Error in error handler for listener {}", 
                        listener.getListenerName(), errorHandlingException);
            }
        }
    }
    
    /**
     * 启动事件处理线程
     */
    private void startEventProcessingThread() {
        Thread eventProcessingThread = new Thread(() -> {
            while (running) {
                try {
                    ProcessingEvent event = eventQueue.poll(1, TimeUnit.SECONDS);
                    if (event != null) {
                        processEvent(event);
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    log.error("Error in event processing thread", e);
                }
            }
        });
        
        eventProcessingThread.setName("EventProcessingThread");
        eventProcessingThread.setDaemon(true);
        eventProcessingThread.start();
        
        log.info("Event processing thread started");
    }
    
    /**
     * 启动定期清理线程
     */
    private void startCleanupThread() {
        scheduledExecutor.scheduleAtFixedRate(() -> {
            try {
                // 清理过期事件（如果有持久化队列的话）
                // 这里可以添加清理逻辑
                log.debug("Performed periodic cleanup");
            } catch (Exception e) {
                log.error("Error in cleanup thread", e);
            }
        }, 5, 5, TimeUnit.MINUTES);
    }
    
    /**
     * 按优先级排序监听器
     * 
     * @param listenerList 监听器列表
     */
    private void sortListenersByPriority(List<ProcessingEventListener> listenerList) {
        listenerList.sort((l1, l2) -> Integer.compare(l2.getPriority(), l1.getPriority()));
    }
    
    /**
     * 获取监听器支持的事件类型
     * 
     * @param listener 监听器
     * @return 支持的事件类型集合
     */
    private Set<ProcessingEvent.EventType> getListenerEventTypes(ProcessingEventListener listener) {
        Set<ProcessingEvent.EventType> supportedTypes = new HashSet<>();
        for (ProcessingEvent.EventType eventType : ProcessingEvent.EventType.values()) {
            if (listener.supportsEventType(eventType)) {
                supportedTypes.add(eventType);
            }
        }
        return supportedTypes;
    }
    
    /**
     * 获取所有注册的监听器
     * 
     * @return 监听器映射
     */
    public Map<String, ProcessingEventListener> getAllListeners() {
        return new HashMap<>(listenerRegistry);
    }
    
    /**
     * 获取指定事件类型的监听器数量
     * 
     * @param eventType 事件类型
     * @return 监听器数量
     */
    public int getListenerCount(ProcessingEvent.EventType eventType) {
        List<ProcessingEventListener> eventListeners = listeners.get(eventType);
        return eventListeners != null ? eventListeners.size() : 0;
    }
    
    /**
     * 获取事件队列大小
     * 
     * @return 队列大小
     */
    public int getEventQueueSize() {
        return eventQueue.size();
    }
    
    /**
     * 获取管理器统计信息
     * 
     * @return 统计信息
     */
    public Map<String, Object> getStatistics() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalListeners", listenerRegistry.size());
        stats.put("eventQueueSize", eventQueue.size());
        stats.put("running", running);
        
        // 按事件类型统计监听器数量
        Map<String, Integer> listenersByType = new HashMap<>();
        for (Map.Entry<ProcessingEvent.EventType, List<ProcessingEventListener>> entry : listeners.entrySet()) {
            listenersByType.put(entry.getKey().name(), entry.getValue().size());
        }
        stats.put("listenersByEventType", listenersByType);
        
        // 按监听器类型统计
        Map<String, Long> listenersByListenerType = listenerRegistry.values().stream()
                .collect(Collectors.groupingBy(
                        l -> l.getListenerType().name(),
                        Collectors.counting()
                ));
        stats.put("listenersByType", listenersByListenerType);
        
        return stats;
    }
    
    /**
     * 清空所有监听器
     */
    public void clearAllListeners() {
        listeners.clear();
        listenerRegistry.clear();
        log.info("Cleared all event listeners");
    }
    
    /**
     * 关闭事件管理器
     */
    public void shutdown() {
        running = false;
        
        // 关闭线程池
        asyncExecutor.shutdown();
        scheduledExecutor.shutdown();
        
        try {
            if (!asyncExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                asyncExecutor.shutdownNow();
            }
            if (!scheduledExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
                scheduledExecutor.shutdownNow();
            }
        } catch (InterruptedException e) {
            asyncExecutor.shutdownNow();
            scheduledExecutor.shutdownNow();
            Thread.currentThread().interrupt();
        }
        
        log.info("Event manager shutdown completed");
    }
}